/*
 * Copyright (C) 2005-2008 Marc Boris Duerner
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include "cxxtools/char.h"
#include "cxxtools/string.h"
#include "cxxtools/utf8codec.h"
#include <ostream>

#ifdef CXXTOOLS_WITH_STD_LOCALE
#include "facets.cpp"

namespace std {

std::locale::id ctype<cxxtools::Char>::id;

#if (defined _MSC_VER || defined __QNX__ || defined __xlC__)

ctype<cxxtools::Char>::ctype(size_t refs)
: ctype_base(refs)
{ }

#else

ctype<cxxtools::Char>::ctype(size_t refs)
: locale::facet(refs)
{ }

#endif


ctype<cxxtools::Char>::~ctype()
{
}


bool ctype<cxxtools::Char>::do_is(mask m, cxxtools::Char c) const
{
    return (m & ctypeMask(c)) != 0;
}


const cxxtools::Char*
ctype<cxxtools::Char>::do_is(const cxxtools::Char* begin, const cxxtools::Char* end, mask* vec) const
{
    for( ; begin < end; ++begin)
    {
        *vec = ctypeMask(*begin);
        ++vec;
    }

    return end;
}


const cxxtools::Char*
ctype<cxxtools::Char>::do_scan_is(mask m, const cxxtools::Char* begin, const cxxtools::Char* end) const
{
    while( begin != end && !is(m,*begin))
    {
        ++begin;
    }

    return begin;
}


const cxxtools::Char*
ctype<cxxtools::Char>::do_scan_not(mask m, const cxxtools::Char* begin, const cxxtools::Char* end) const
{
    while( begin != end && is(m,*begin))
    {
        ++begin;
    }

    return begin;
}


cxxtools::Char
ctype<cxxtools::Char>::do_toupper(cxxtools::Char ch) const
{
    return toupper(ch);
}


const cxxtools::Char*
ctype<cxxtools::Char>::do_toupper(cxxtools::Char* begin, const cxxtools::Char* end) const
{
    for(; begin < end; ++begin)
    {
        *begin = do_toupper(*begin);
    }

    return end;
}


cxxtools::Char
ctype<cxxtools::Char>::do_tolower(cxxtools::Char ch) const
{
    return tolower(ch);
}


const cxxtools::Char*
ctype<cxxtools::Char>::do_tolower(cxxtools::Char* begin, const cxxtools::Char* end) const
{
    for(; begin < end; ++begin) {
        *begin = do_tolower(*begin);
    }

    return end;
}


cxxtools::Char ctype<cxxtools::Char>::do_widen(char ch) const
{
    return cxxtools::Char(static_cast<unsigned char>(ch));
}


const char* ctype<cxxtools::Char>::do_widen(const char* begin, const char* end, cxxtools::Char* dest) const
{
    for(const char* cur = begin; cur < end; ++cur) {
        *dest = do_widen(*cur);
        ++dest;
    }

    return end;
}


char ctype<cxxtools::Char>::do_narrow(cxxtools::Char ch, char dfault) const
{
    return ch.narrow(dfault);
}


const cxxtools::Char*
ctype<cxxtools::Char>::do_narrow(const cxxtools::Char* begin, const cxxtools::Char* end, char dfault, char* dest) const
{
    for(const cxxtools::Char* cur = begin; cur < end; ++cur) {
        *dest = do_narrow(*cur, dfault);
        ++dest;
    }

    return end;
}

} // namespace std

#endif

namespace cxxtools {

std::ostream& operator<< (std::ostream& out, Char ch)
{
    Utf8Codec codec;
    char to[16];
    MBState state;

    Utf8Codec::result r;

    const Char* from_next;

    char* to_next = to;
    r = codec.out(state, &ch, &ch + 1, from_next, to, to + sizeof(to), to_next);

    if (r == Utf8Codec::error)
    {
        out.setstate(std::ios::failbit);
    }
    else
    {
        out.write(to, to_next - to);
    }

    return out;
}

const unsigned short ctype_lookup1[69] =
{
  0,    104,  169,  257,  385,  402,  402,  498,
  626,  626,  677,  755,  402,  402,  402,  402,
  402,  402,  402,  402,  402,  402,  402,  402,
  402,  402,  402,  402,  402,  402,  402,  402,
  402,  402,  402,  402,  402,  402,  402,  402,
  402,  402,  402,  402,  402,  402,  402,  402,
  402,  402,  402,  402,  402,  402,  402,  402,
  883,  402,  402,  402,  1011, 1011, 1011, 1012,
  1011, 1011, 1011, 1012, 0
};


const unsigned short ctype_lookup2[1141] =
{
  0,     127,   255,   382,   502,   582,   710,   837,
  965,   1091,  1219,  1339,  1467,  1580,  1708,  1836,
  1886,  1886,  2013,  2140,  2267,  2394,  2521,  2647,
  2774,  2900,  3026,  3152,  3279,  3406,  3534,  3662,
  3790,  3886,  4014,  4069,  4197,  4318,  4431,  4556,
  4683,  4684,  4684,  4684,  4703,  4831,  4959,  5087,
  5215,  5343,  5471,  5588,  1886,  1886,  1886,  1886,
  1886,  1886,  5716,  1886,  5844,  5950,  6078,  6206,
  6334,  6462,  6590,  6714,  6830,  6830,  6958,  7083,
  7211,  7311,  7439,  7512,  7640,  7768,  7895,  8013,
  7439,  7439,  6830,  8138,  6830,  6830,  8266,  1886,
  1886,  1886,  1886,  1886,  1886,  8394,  7439,  8424,
  8552,  8657,  8785,  8898,  9026,  9154,  7439,  7439,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  9282,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  9410,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  9538,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  9666,  9794,  9794,  9794,  9794,  9794,  9794,  9794,
  9794,  9794,  9794,  9794,  9794,  9794,  9794,  9794,
  9794,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  4684,  4684,  10050, 1886,  10178,
  10256, 4684,  4684,  10339, 10451, 10579, 10697, 10825,
  10938, 11066, 11194, 11322, 1886,  1886,  1886,  11450,
  11578, 11706, 11804, 1886,  1886,  1886,  1886,  1886,
  1886,  11932, 1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  7439,  12060, 12188, 12313, 1886,  1886,
  12441, 1886,  12569, 12695, 12819, 12941, 12965, 13083,
  13153, 13223, 1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  4684,  4684,  4684,  4684,  4684,  4684,
  4684,  4684,  13351, 1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  4684,  4684,  4684,  4684,  13408,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  13535, 1886,  13663, 13679, 1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  1886,  1886,  1886,  1886,  1886,
  1886,  1886,  1886,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  9922,  9922,  9922,  9922,  9922,
  9922,  9922,  9922,  13807, 0
};


#include "unicode.h"


const unsigned short upper_lookup1[69]=
{
  0,    74,   74,   76,   203,  74,   74,   74,
  74,   74,   74,   74,   74,   74,   74,   74,
  74,   74,   74,   74,   74,   74,   74,   74,
  74,   74,   74,   74,   74,   74,   74,   74,
  74,   74,   74,   74,   74,   74,   74,   74,
  74,   74,   74,   74,   74,   74,   74,   74,
  74,   74,   74,   74,   74,   74,   74,   74,
  74,   74,   74,   74,   74,   74,   74,   74,
  74,   74,   74,   74, 0
};


const unsigned short upper_lookup2[332]=
{
  0,     123,   251,   379,   499,   627,   686,   770,
  894,   1020,  1147,  1268,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1402,  1508,  1636,  1764,
  1275,  1275,  1880,  1275,  1275,  1275,  1275,  1275,
  1275,  2008,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  32,    1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  2114,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,  1275,  1275,  1275,  1275,  1275,
  1275,  1275,  1275,0
};


const short upper_data[2243]=
{
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,    -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,
  -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,    0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   743,   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,    -32,   -32,   -32,   -32,   -32,
  -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,
  -32,   -32,    0,    -32,   -32,   -32,   -32,   -32,   -32,   -32,    121,   0,    -1,     0,    -1,     0,
  -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,
  -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,
  -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -232,   0,    -1,     0,
  -1,     0,    -1,     0,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,
  -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,
  -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,
  -1,     0,    -1,     0,     0,    -1,     0,    -1,     0,    -1,    -300,   0,     0,     0,    -1,     0,
  -1,     0,     0,    -1,     0,     0,     0,    -1,     0,     0,     0,     0,     0,    -1,     0,     0,
   97,    0,     0,     0,    -1,     0,     0,     0,     0,     130,   0,     0,    -1,     0,    -1,     0,
  -1,     0,     0,    -1,     0,     0,     0,     0,    -1,     0,     0,    -1,     0,     0,     0,    -1,
   0,    -1,     0,     0,    -1,     0,     0,     0,    -1,     0,     56,    0,     0,     0,     0,     0,
  -1,    -2,     0,    -1,    -2,     0,    -1,    -2,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,    -79,    0,    -1,     0,    -1,     0,    -1,     0,
  -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,     0,    -1,    -2,     0,
  -1,     0,     0,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,
  -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,
  -1,     0,    -1,     0,     0,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,
  -1,     0,    -1,     0,    -1,     0,    -1,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,    -210,  -206,   0,    -205,  -205,   0,    -202,   0,    -203,   0,
   0,     0,     0,    -205,   0,     0,    -207,   0,     0,     0,     0,    -209,  -211,   0,     0,     0,
   0,     0,    -211,   0,     0,    -213,   0,     0,    -214,   0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,    -218,   0,     0,    -218,   0,     0,     0,     0,    -218,   0,    -217,  -217,   0,
   0,     0,     0,     0,     0,    -219,   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     84,    0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,    -38,   -37,
  -37,   -37,    0,    -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,
  -32,   -32,   -32,   -32,   -31,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -64,   -63,
  -63,    0,    -62,   -57,    0,     0,     0,    -47,   -54,    0,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,    -86,   -80,    7,     0,     0,    -96,    0,     0,    -1,     0,     0,    -1,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,    -32,   -32,
  -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,
  -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -80,   -80,
  -80,   -80,   -80,   -80,   -80,   -80,   -80,   -80,   -80,   -80,   -80,   -80,   -80,   -80,    0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,     0,
   0,     0,     0,     0,     0,     0,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,     0,    -1,     0,
  -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,     0,     0,    -1,     0,     0,     0,     0,     0,     0,    -1,     0,    -1,     0,
  -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,    -48,   -48,   -48,   -48,
  -48,   -48,   -48,   -48,   -48,   -48,   -48,   -48,   -48,   -48,   -48,   -48,   -48,   -48,   -48,   -48,
  -48,   -48,   -48,   -48,   -48,   -48,   -48,   -48,   -48,   -48,   -48,    0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,     0,     0,     0,     0,    -59,
   0,     0,     0,     0,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,
   0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,    -1,     0,     0,
   0,     0,     0,     0,     8,     8,     8,     8,     8,     8,     8,     8,     0,     0,     0,     0,
   0,     0,     0,     0,     8,     8,     8,     8,     8,     8,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     8,     8,     8,     8,     8,     8,     8,     8,     0,     0,     0,     0,
   0,     0,     0,     0,     8,     8,     8,     8,     8,     8,     8,     8,     0,     0,     0,     0,
   0,     0,     0,     0,     8,     8,     8,     8,     8,     8,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     8,     0,     8,     0,     8,     0,     8,     0,     0,     0,     0,
   0,     0,     0,     0,     8,     8,     8,     8,     8,     8,     8,     8,     0,     0,     0,     0,
   0,     0,     0,     0,     74,    74,    86,    86,    86,    86,    100,   100,   128,   128,   112,   112,
   126,   126,   0,     0,     8,     8,     8,     8,     8,     8,     8,     8,     0,     0,     0,     0,
   0,     0,     0,     0,     8,     8,     8,     8,     8,     8,     8,     8,     0,     0,     0,     0,
   0,     0,     0,     0,     8,     8,     8,     8,     8,     8,     8,     8,     0,     0,     0,     0,
   0,     0,     0,     0,     8,     8,     0,     9,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,    -7205,  0,     0,     0,     0,     9,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     8,     8,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     8,     8,     0,     0,     0,     7,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     9,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,    -16,   -16,   -16,   -16,   -16,   -16,   -16,   -16,
  -16,   -16,   -16,   -16,   -16,   -16,   -16,   -16,    0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,    -26,   -26,   -26,   -26,   -26,   -26,   -26,   -26,
  -26,   -26,   -26,   -26,   -26,   -26,   -26,   -26,   -26,   -26,   -26,   -26,   -26,   -26,   -26,   -26,
  -26,   -26,    0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,    -40,   -40,   -40,   -40,   -40,   -40,
  -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,
  -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,
  -40,   -40,    0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0
};


const unsigned short lower_lookup1[69]=
{
  0,    74,   74,   76,   203,  74,   74,   74,
  74,   74,   74,   74,   74,   74,   74,   74,
  74,   74,   74,   74,   74,   74,   74,   74,
  74,   74,   74,   74,   74,   74,   74,   74,
  74,   74,   74,   74,   74,   74,   74,   74,
  74,   74,   74,   74,   74,   74,   74,   74,
  74,   74,   74,   74,   74,   74,   74,   74,
  74,   74,   74,   74,   74,   74,   74,   74,
  74,   74,   74,   7,    0
};


const unsigned short lower_lookup2[332]=
{
  0,     91,    219,   346,   466,   517,   517,   639,
  767,   893,   1021,  517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   1149,  1255,  1376,  1496,
  517,   517,   1621,  517,   517,   517,   517,   517,
  517,   1733,  517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   1828,  517,   517,   517,   517,   517,
  517,   517,   517,   1956,  517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   517,   517,   517,   517,   517,
  517,   517,   517,   0
};


const short lower_data[2085]=
{
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,
   32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     32,    32,    32,    32,    32,
   32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,
   32,    32,    0,     32,    32,    32,    32,    32,    32,    32,    0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,    -199,   0,     1,     0,     1,
   0,     1,     0,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,
   1,     0,     1,     0,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,    -121,   1,     0,     1,     0,     1,     0,     0,     210,   1,     0,     1,     0,
   206,   1,     0,     205,   205,   1,     0,     0,     79,    202,   203,   1,     0,     205,   207,   0,
   211,   209,   1,     0,     0,     0,     211,   213,   0,     214,   1,     0,     1,     0,     1,     0,
   218,   1,     0,     218,   0,     0,     1,     0,     218,   1,     0,     217,   217,   1,     0,     1,
   0,     219,   1,     0,     0,     0,     1,     0,     0,     0,     0,     0,     0,     0,     2,     1,
   0,     2,     1,     0,     2,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     0,     1,     0,     1,     0,     1,     0,     1,     0,
   1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     0,     2,     1,     0,     1,     0,
  -97,   -56,    1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,
   1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,
   1,     0,    -130,   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,
   1,     0,     1,     0,     1,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     38,    0,     37,    37,    37,    0,     64,    0,     63,    63,    0,
   32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,
   32,    0,     32,    32,    32,    32,    32,    32,    32,    32,    32,    0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     0,
   0,     0,     0,    -60,    0,     0,     1,     0,    -7,     1,     0,     0,     0,     0,     0,     80,
   80,    80,    80,    80,    80,    80,    80,    80,    80,    80,    80,    80,    80,    80,    80,    32,
   32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,
   32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     0,     1,     0,
   1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     0,     0,     1,     0,     0,     0,     0,     0,     0,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     48,    48,
   48,    48,    48,    48,    48,    48,    48,    48,    48,    48,    48,    48,    48,    48,    48,    48,
   48,    48,    48,    48,    48,    48,    48,    48,    48,    48,    48,    48,    48,    48,    48,    48,
   48,    48,    48,    48,    0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
   0,     0,     0,     0,     0,     0,     0,     0,    -8,    -8,    -8,    -8,    -8,    -8,    -8,    -8,
   0,     0,     0,     0,     0,     0,     0,     0,    -8,    -8,    -8,    -8,    -8,    -8,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,    -8,    -8,    -8,    -8,    -8,    -8,    -8,    -8,
   0,     0,     0,     0,     0,     0,     0,     0,    -8,    -8,    -8,    -8,    -8,    -8,    -8,    -8,
   0,     0,     0,     0,     0,     0,     0,     0,    -8,    -8,    -8,    -8,    -8,    -8,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,    -8,     0,    -8,     0,    -8,     0,    -8,
   0,     0,     0,     0,     0,     0,     0,     0,    -8,    -8,    -8,    -8,    -8,    -8,    -8,    -8,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
  -8,    -8,    -8,    -8,    -8,    -8,    -8,    -8,     0,     0,     0,     0,     0,     0,     0,     0,
  -8,    -8,    -8,    -8,    -8,    -8,    -8,    -8,     0,     0,     0,     0,     0,     0,     0,     0,
  -8,    -8,    -8,    -8,    -8,    -8,    -8,    -8,     0,     0,     0,     0,     0,     0,     0,     0,
  -8,    -8,    -74,   -74,   -9,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
  -86,   -86,   -86,   -86,   -9,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
  -8,    -8,    -100,  -100,   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
  -8,    -8,    -112,  -112,  -7,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
  -128,  -128,  -126,  -126,  -9,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,    -7517,  0,     0,     0,    -8383,
  -8262,  0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     16,    16,    16,    16,    16,    16,    16,    16,    16,    16,    16,
   16,    16,    16,    16,    16,    0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     26,    26,    26,    26,    26,
   26,    26,    26,    26,    26,    26,    26,    26,    26,    26,    26,    26,    26,    26,    26,    26,
   26,    26,    26,    26,    26,    0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,
   32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    32,    0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     40,    40,    40,    40,    40,    40,    40,    40,    40,    40,    40,    40,
   40,    40,    40,    40,    40,    40,    40,    40,    40,    40,    40,    40,    40,    40,    40,    40,
   40,    40,    40,    40,    40,    40,    40,    40,    40,    40,    40,    40,    0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   0,     0,     0,     0,     0
};


Char tolower(const cxxtools::Char& ch)
{
    const cxxtools::Char::value_type ucs = ch.value();
    return Char(ucs + lower_data[lower_lookup2[lower_lookup1[ucs>>14]+((ucs>>7)&127)]+(ucs&127)]);
}


Char toupper(const Char& ch)
{
    const cxxtools::Char::value_type ucs = ch.value();
    return Char(ucs + upper_data[upper_lookup2[upper_lookup1[ucs>>14]+((ucs>>7)&127)]+(ucs&127)]);
}


std::ctype_base::mask ctypeMask(const Char& ch)
{
    const cxxtools::Char::value_type c = ch.value();
    return ctype_data[ ctype_lookup2[ ctype_lookup1[c>>14]+((c>>7)&127) ]+(c&127) ];
}

} // namespace cxxtools
